package com.lfy.modules.blog.aop;

import com.lfy.modules.common.intercept.AuthHandlerInterceptor;
import com.lfy.modules.blog.domain.RoleEntity;
import com.lfy.modules.common.domain.entity.UserEntity;
import com.lfy.modules.blog.service.RoleService;
import com.lfy.modules.common.anno.CheckRole;
import com.lfy.modules.common.custom.constants.AuthConstant;
import com.lfy.modules.common.domain.BaseEnum;
import com.lfy.modules.common.domain.R;
import com.lfy.modules.common.utils.SpElUtils;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Objects;
/**
 *  越权处理
 *
 * @author <a href="https://www.lvfeiy.top">lvfeiyang</a>
 * @date 2024/4/25 1:02
 */
@Aspect
@Component
@Slf4j
public class RoleAspect {
    @Resource
    private RoleService service;
    @Pointcut("@annotation(com.lfy.modules.common.anno.CheckRole)")
    public void cut() {

    }
    @Around("cut()")
    public Object before(ProceedingJoinPoint joinPoint) throws Throwable {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        CheckRole annotation = signature.getMethod().getAnnotation(CheckRole.class);
        UserEntity userEntity = AuthHandlerInterceptor.authLocal.get();
        RoleEntity userRole = null;
        String roleIdEl = annotation.roleId();
        if(!StringUtils.isEmpty(roleIdEl)){
            String rowId = SpElUtils.parseSpEl(signature.getMethod(), joinPoint.getArgs(), roleIdEl);
            if(!Objects.isNull(rowId)){
             userRole = this.service.getById(userEntity.getRole());

            RoleEntity paramsRole = this.service.getById(Long.parseLong(rowId));
            if(paramsRole.getRoleLev() < userRole.getRoleLev()){
                return R.error(BaseEnum.authEnum.NO_AUTH);
            }
        }
        String levelEl = annotation.level();
        if(!StringUtils.isEmpty(levelEl)){
            String level = SpElUtils.parseSpEl(signature.getMethod(), joinPoint.getArgs(), levelEl);
            if(Objects.isNull(userRole)) {
                userRole = this.service.getById(userEntity.getRole());
            }
            if(Objects.isNull(userRole)){
                log.error("userRole is null:{}" ,userEntity);
                return R.error(BaseEnum.authEnum.NO_AUTH);
            }
            Integer roleLev = userRole.getRoleLev();
            if(Integer.parseInt(level) < roleLev){
                return R.error(BaseEnum.authEnum.NO_AUTH);
            }
        }
        }

        return joinPoint.proceed();
    }
}
